/* Liviu Patrasco & Holly Beach
 * TCSS422 Project 1: Web Crawler
 * February 6, 2012
 */

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * The PageAnalyzer acts as a consumer
 * class that collects statistical data
 * in a single threaded environment.
 * @author Liviu and Holly
 */
public class PageAnalyzer {
	private Map<String, Integer> keywords_map;
	private String[] keywords; //used to display keywords in input order
	private double avg_words_per_page = 0;
	private double avg_links_per_page = 0;
	private double avg_parse_time = 0;
	private long total_parse_time = 0;
	private int total_pages =0;
	
	public PageAnalyzer(final String[] words) {
		keywords_map = new HashMap<String, Integer>();
		keywords = words;
		for (String word: words) {
			keywords_map.put(word, 0);
		}
	}
	/**
	 * 
	 * @return # of pages analyzed
	 */
	public int totalPages(){
		return total_pages;
	}
	
	/**
	 * 
	 * @param pages a list of parsed pages to analyze
	 */
	public void analyze(final List<Page> pages) {
		int total_words = 0;
		int total_links = 0;
		total_pages = 0;
		for (Page p : pages) {
			total_words += p.getText().split(" ").length;
			total_links += p.getLinks().size();
			total_parse_time+=p.getParseTime();
			total_pages++;
			analyzeKeywords(p);
		}
		if(total_pages > 0){
			avg_words_per_page = total_words / total_pages;
			avg_links_per_page = total_links / total_pages;
			avg_parse_time = total_parse_time / total_pages;
		}
	}
	
	public String toString() {
		StringBuilder str = new StringBuilder();
		str.append("\nPages retrieved: ");
		str.append(total_pages);
		str.append("\n");
		str.append("Average words per page: ");
		str.append(avg_words_per_page);
		str.append("\n");
		str.append("Average URLs per page: ");
		str.append(avg_links_per_page);
		str.append("\n\n");
		str.append(String.format(
				"%-20s%-20s%15s","Keyword", "Avg Hits Per Page", "TotalHits\n"));
		for (String kw : keywords){
			int cnt = keywords_map.get(kw);
			if (total_pages == 0){
				str.append(String.format(
					"%-3s%-20s%8d%20d\n"," ", kw,total_pages,cnt));		
			}else{
				str.append(String.format(
					"%-3s%-20s%8.2f%20d\n"," ", kw,((float)cnt/total_pages),cnt));
			}
		}
		str.append("\nAverage parse time per page: ");
		str.append(String.format("%.4f sec\n", avg_parse_time/1000f));
		return str.toString();
	}
	
	/**
	 * 
	 * @param p page to analyze for keywords
	 */
	private void analyzeKeywords(final Page p) {
		for (String k_word : keywords){
			int k_word_count = 0;
			Pattern keyword = Pattern.compile("\\b" + k_word + "\\b", Pattern.CASE_INSENSITIVE);
			Matcher matcher = keyword.matcher(p.getText());
			
			while (matcher.find()) {
				k_word_count++;
			}
			keywords_map.put(k_word, keywords_map.get(k_word) + k_word_count);
			}
	}
}
